package com.zlsy.thread.threadpool;


import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhouliang
 * @date 2020/7/4 15:29
 * <p>
 * 演示每个任务执行的前后放钩子函数
 */
public class CanBeSuspendedThreadPool extends ThreadPoolExecutor {

    private boolean isPaused;

    private final Lock lock = new ReentrantLock();
    private Condition unpaused = lock.newCondition();

    public CanBeSuspendedThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }


    /**
     * 重新在线程池执行之前的动作！
     *
     * @param t
     * @param r
     */
    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        lock.lock();
        try {
            //如果需要停止线程池
            while (isPaused) {
                //停止
                unpaused.await();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private void pause() {
        lock.lock();
        try {
            isPaused = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


    private void resume() {
        lock.lock();
        try {
            isPaused = false;
            //唤醒全部的线程
            unpaused.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        CanBeSuspendedThreadPool threadPool = new CanBeSuspendedThreadPool(
                10,
                20,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>());

        for (int i = 0; i < 10000; i++) {
            threadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + " 我被执行了");
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        //在执行了1500毫秒以后我们暂停线程池的使用
        TimeUnit.MILLISECONDS.sleep(1500);
        threadPool.pause();
        System.out.println("线程池被暂停了！");

        //然后过了1000毫秒又开启线程池
        TimeUnit.MILLISECONDS.sleep(1000);

        threadPool.resume();

//        threadPool.shutdown();
    }

}
